﻿using System;
using System.Collections.Generic;
using Engine;
using Engine.Graphics;
using Engine.Media;
using Game;
using GameEntitySystem;
using TemplatesDatabase;

namespace Game
{
    /// <summary>
    /// 地图核心组件，负责地图渲染、更新、输入处理等功能
    /// </summary>
    public class ComponentMap : Component, IDrawable, IUpdateable
    {
        /// <summary>
        /// 小地图显示区域的矩形控件
        /// </summary>
        public RectangleWidget SmallSquare { get; set; }

        /// <summary>
        /// 方块颜色处理器
        /// </summary>
        private BlockColorProcessor _colorProcessor;

        /// <summary>
        /// 地图尺寸属性
        /// </summary>
        public int MapSize
        {
            get => m_mapSize;
            set => m_mapSize = MathUtils.Clamp(value, 100, 1000);
        }

        /// <summary>
        /// 地图可见性属性
        /// </summary>
        public bool IsVisible
        {
            get => m_isVisible;
            set => m_isVisible = value;
        }

        /// <summary>
        /// 加载地图设置按钮
        /// </summary>
        private void LoadMapButton()
        {
            ContainerWidget guiWidget = m_componentPlayer.GuiWidget;
            mapButton = guiWidget.Children.Find<ButtonWidget>("MapSetButton", true);
            string language = "en-US";
            try
            {
                if (ModsManager.Configs != null && ModsManager.Configs.TryGetValue("Language", out string lang))
                {
                    language = lang ?? "en-US";
                }
            }
            catch
            {
                // 保持默认语言
            }
            mapButton.Text = language.Equals("zh-CN", StringComparison.OrdinalIgnoreCase) ? "设置" : "Settings";
        }

        /// <summary>
        /// 处理用户输入
        /// </summary>
        public void HandleInput()
        {
            if (m_componentPlayer.GameWidget.Input.IsKeyDownOnce(Engine.Input.Key.Delete) ||
                (mapButton != null && mapButton.IsClicked))
            {
                if (m_componentPlayer.ComponentGui.ModalPanelWidget is MapSettingsWidget)
                {
                    m_componentPlayer.ComponentGui.ModalPanelWidget = null;
                    return;
                }
                m_componentPlayer.ComponentGui.ModalPanelWidget = new MapSettingsWidget(m_componentPlayer);
            }
        }

        /// <summary>
        /// 初始化地图
        /// </summary>
        private void InitializeMap()
        {
            MapTexture = new Texture2D(MapSize, MapSize, 1, 0);
            InitializeBorderTexture();
            UpdateMap();
        }

        /// <summary>
        /// 初始化地图边框纹理
        /// </summary>
        private void InitializeBorderTexture()
        {
            Image image = new Image(MapSize + 10, MapSize + 10);
            int centerX = image.Width / 2;
            int centerY = image.Height / 2;
            int radius = MapSize / 2;

            // 填充透明背景
            for (int i = 0; i < image.Width; i++)
            {
                for (int j = 0; j < image.Height; j++)
                {
                    image.SetPixel(i, j, Color.Transparent);
                }
            }

            // 绘制边框圆环
            for (int r = radius; r <= radius + 5; r++)
            {
                DrawCirclePixels(image, centerX, centerY, r, new Color(255, 255, 255));
            }

            BorderTexture = Texture2D.Load(image, 1);
        }

        /// <summary>
        /// 绘制圆形像素点
        /// </summary>
        private void DrawCirclePixels(Image image, int centerX, int centerY, int radius, Color color)
        {
            for (int x = -radius; x <= radius; x++)
            {
                for (int y = -radius; y <= radius; y++)
                {
                    if (x * x + y * y <= radius * radius &&
                        x * x + y * y >= (radius - 1) * (radius - 1))
                    {
                        int pixelX = centerX + x;
                        int pixelY = centerY + y;
                        if (pixelX >= 0 && pixelX < image.Width && pixelY >= 0 && pixelY < image.Height)
                        {
                            image.SetPixel(pixelX, pixelY, color);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 绘制纹理
        /// </summary>
        public void DrawTexture(Texture2D texture2D, Vector2 position, float rotation, Vector2 size, Color color)
        {
            TexturedBatch2D texturedBatch2D = new PrimitivesRenderer2D()
                .TexturedBatch(texture2D, false, 0, DepthStencilState.None, null, BlendState.AlphaBlend, SamplerState.PointClamp);
            Vector2 center = position + size / 2f;
            Vector2 corner = position + size;
            texturedBatch2D.QueueQuad(position, corner, 1f, Vector2.Zero, Vector2.One, color);
            Matrix matrix = Matrix.CreateTranslation(-center.X, -center.Y, 0f)
                          * Matrix.CreateRotationZ(rotation)
                          * Matrix.CreateTranslation(center.X, center.Y, 0f);
            texturedBatch2D.TransformTriangles(matrix, 0, -1);
            texturedBatch2D.Flush(true);
        }

        /// <summary>
        /// 更新地图纹理（核心修复：确保使用自定义Image类处理像素）
        /// </summary>
        public void UpdateMap()
        {
            int visibilityRange = SettingsManager.VisibilityRange;
            Vector3 position = m_componentPlayer.ComponentBody.Position;
            Image image = new Image(visibilityRange, visibilityRange); // 使用自定义Image类

            bool[,] circularMask = CreateCircularMask(visibilityRange);

            // 填充地图像素
            for (int i = 0; i < visibilityRange; i++)
            {
                for (int j = 0; j < visibilityRange; j++)
                {
                    if (circularMask[i, j])
                    {
                        int worldX = i + (int)position.X - visibilityRange / 2;
                        int worldZ = j + (int)position.Z - visibilityRange / 2;
                        int topContent = GetTopContent(worldX, worldZ);
                        Color blockColor = _colorProcessor.GetColor(topContent, position, worldX, worldZ);
                        image.SetPixel(i, j, blockColor); // 使用自定义Image的SetPixel方法
                    }
                    else
                    {
                        image.SetPixel(i, j, Color.Transparent);
                    }
                }
            }

            // 释放旧纹理并加载新纹理（使用项目内方法）
            if (MapTexture != null)
            {
                MapTexture.Dispose();
            }
            MapTexture = Texture2D.Load(image, 1); // 确保Texture2D.Load接受自定义Image
        }

        /// <summary>
        /// 从字节数组更新纹理（新增方法：处理byte[]转换为Image）
        /// </summary>
        public void UpdateMapFromByteArray(byte[] pixelBuffer, int width, int height)
        {
            if (pixelBuffer == null || pixelBuffer.Length != width * height * 4)
                throw new ArgumentException("无效的像素缓冲区");

            Image image = new Image(width, height);
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    int index = (y * width + x) * 4;
                    Color color = new Color(
                        pixelBuffer[index],     // R
                        pixelBuffer[index + 1], // G
                        pixelBuffer[index + 2], // B
                        pixelBuffer[index + 3]  // A
                    );
                    image.SetPixel(x, y, color);
                }
            }

            if (MapTexture != null)
            {
                MapTexture.Dispose();
            }
            MapTexture = Texture2D.Load(image, 1);
        }

        /// <summary>
        /// 获取指定坐标的顶层方块
        /// </summary>
        public int GetTopContent(int pointX, int pointZ)
        {
            int topHeight = m_subsystemTerrain.Terrain.GetTopHeight(pointX, pointZ);
            int content = m_subsystemTerrain.Terrain.GetCellContents(pointX, topHeight, pointZ);

            // 特殊方块处理（穿透植被取地面）
            if (content == 28 || content == 99 || content == 19 || content == 174 || content == 25)
            {
                content = m_subsystemTerrain.Terrain.GetCellContents(pointX, topHeight - 1, pointZ);
            }
            // 液体方块统一处理
            if (content == 226 || content == 229 || content == 232 || content == 233)
            {
                content = 18;
            }
            return content;
        }

        /// <summary>
        /// 绘制地图
        /// </summary>
        public void Draw(Camera camera, int drawOrder)
        {
            if (SmallSquare == null || !SmallSquare.IsVisible || !IsVisible)
                return;

            if (MapTexture != null && BorderTexture != null)
            {
                Vector2 actualSize = SmallSquare.ActualSize;
                Vector2 center = SmallSquare.GlobalTransform.Translation.XY + actualSize / 2f;
                Vector2 halfMapSize = new Vector2(MapSize, MapSize) / 2f;

                // 绘制地图纹理
                DrawTexture(MapTexture, center - halfMapSize, 0f, halfMapSize * 2f, Color.White);

                // 绘制边框
                Vector2 borderHalfSize = halfMapSize + new Vector2(5f, 5f);
                DrawTexture(BorderTexture, center - borderHalfSize, 0f, borderHalfSize * 2f, Color.White);

                // 绘制玩家方向箭头
                DrawPlayerArrow(center);
            }
        }

        /// <summary>
        /// 绘制玩家方向箭头
        /// </summary>
        private void DrawPlayerArrow(Vector2 center)
        {
            if (ArrowTexture == null)
                return;

            Vector2 forward = m_componentPlayer.ComponentBody.Matrix.Forward.XZ;
            float rotation = MathUtils.Atan2(forward.Y, forward.X) + MathUtils.DegToRad(90f);

            TexturedBatch2D batch = new PrimitivesRenderer2D()
                .TexturedBatch(ArrowTexture, false, 0, DepthStencilState.None, null, BlendState.AlphaBlend, SamplerState.PointWrap);
            batch.QueueQuad(center - new Vector2(16f, 16f), center + new Vector2(16f, 16f), 1f, Vector2.Zero, Vector2.One, Color.White);

            Matrix matrix = Matrix.CreateTranslation(-center.X, -center.Y, 0f)
                          * Matrix.CreateRotationZ(rotation)
                          * Matrix.CreateTranslation(center.X, center.Y, 0f);
            batch.TransformTriangles(matrix, 0, -1);
            batch.Flush(true);
        }

        /// <summary>
        /// 更新组件状态
        /// </summary>
        public void Update(float dt)
        {
            if (SmallSquare == null && m_componentPlayer?.GuiWidget != null)
            {
                SmallSquare = m_componentPlayer.GuiWidget.Children.Find<RectangleWidget>("Smallsquare", true);
            }
            HandleInput();
            UpdateMap();
        }

        /// <summary>
        /// 加载组件数据
        /// </summary>
        public override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap)
        {
            m_componentPlayer = base.Entity.FindComponent<ComponentPlayer>(true);
            m_subsystemTerrain = base.Project.FindSubsystem<SubsystemTerrain>(true);
            ArrowTexture = ContentManager.Get<Texture2D>("Atlases/PlayerSpot");
            ViewportSize = m_componentPlayer.GameWidget.ActiveCamera.ViewportSize;

            LoadBlocksPixelColor();
            LoadMapButton();

            IsVisible = valuesDictionary.GetValue<bool>("MapVisible", true);
            MapSize = valuesDictionary.GetValue<int>("MapSize", 300);

            // 加载地图位置
            float posX = valuesDictionary.GetValue<float>("MapPositionX", InitialSquarePosition.X);
            float posY = valuesDictionary.GetValue<float>("MapPositionY", InitialSquarePosition.Y);
            SmallSquare = m_componentPlayer.GuiWidget.Children.Find<RectangleWidget>("Smallsquare", true);
            if (SmallSquare != null)
            {
                SmallSquare.Margin = new Vector2(posX, posY);
            }

            // 初始化颜色处理器
            _colorProcessor = new BlockColorProcessor(BlockPixelDatas, m_subsystemTerrain);
            InitializeMap();
            m_mapInitialized = true;
        }

        /// <summary>
        /// 实体移除时的清理工作
        /// </summary>
        public override void OnEntityRemoved()
        {
            MapTexture?.Dispose();
            BorderTexture?.Dispose();
            base.OnEntityRemoved();
        }

        /// <summary>
        /// 绘制顺序
        /// </summary>
        public int[] DrawOrders => new[] { 1678 };

        /// <summary>
        /// 更新顺序
        /// </summary>
        public UpdateOrder UpdateOrder => 0;

        /// <summary>
        /// 保存组件数据
        /// </summary>
        public override void Save(ValuesDictionary valuesDictionary, EntityToIdMap entityToIdMap)
        {
            valuesDictionary.SetValue("MapVisible", IsVisible);
            valuesDictionary.SetValue("MapSize", MapSize);
            if (SmallSquare != null)
            {
                valuesDictionary.SetValue("MapPositionX", SmallSquare.Margin.X);
                valuesDictionary.SetValue("MapPositionY", SmallSquare.Margin.Y);
            }
            base.Save(valuesDictionary, entityToIdMap);
        }

        /// <summary>
        /// 加载方块像素颜色数据
        /// </summary>
        public void LoadBlocksPixelColor()
        {
            BlockPixelDatas = BlockPixelDataDictionary.GetBlockPixelDatas();
        }

        /// <summary>
        /// 创建圆形遮罩
        /// </summary>
        private bool[,] CreateCircularMask(int size)
        {
            bool[,] mask = new bool[size, size];
            int radius = size / 2;
            int centerX = radius;
            int centerY = radius;

            for (int x = 0; x < size; x++)
            {
                for (int y = 0; y < size; y++)
                {
                    int dx = x - centerX;
                    int dy = y - centerY;
                    mask[x, y] = (dx * dx + dy * dy) <= (radius * radius);
                }
            }
            return mask;
        }

        // 私有字段
        private ComponentPlayer m_componentPlayer;
        private SubsystemTerrain m_subsystemTerrain;
        private Texture2D MapTexture;
        private Texture2D BorderTexture;
        private Texture2D ArrowTexture;
        private Dictionary<int, BlockPixelData> BlockPixelDatas;
        private Vector2 ViewportSize;
        private int m_mapSize = 300;
        public static readonly Vector2 InitialSquarePosition = new Vector2(1000f, 120f);
        private bool m_isVisible = true;
        private ButtonWidget mapButton;
        private bool m_mapInitialized;
    }
}